package main

import (
	"encoding/json"
	"fmt"
	"syscall/js"
)

type ActorMessage struct {
	Type    string                 `json:"type"`
	Content map[string]interface{} `json:"content,omitempty"`
}

type ActorPID struct {
	ID      string `json:"id"`
	Address string `json:"address"`
}

var (
	// 模拟的 Actor 注册表
	actorRegistry = make(map[string]bool)
	// 下一个可用的 Actor ID
	nextActorID = 1
)

func main() {
	fmt.Println("ProtoActor-Go WASM 模块初始化中...")

	// 注册全局函数
	js.Global().Set("invokeGoFunction", js.FuncOf(invokeGoFunction))

	// 防止程序退出
	c := make(chan struct{}, 0)
	<-c
}

// invokeGoFunction 处理 JS 调用
func invokeGoFunction(this js.Value, args []js.Value) interface{} {
	if len(args) < 2 {
		return marshalResponse(nil, fmt.Errorf("需要提供函数名和参数"))
	}

	funcName := args[0].String()
	argsJSON := args[1].String()

	var params []interface{}
	if argsJSON != "" {
		if err := json.Unmarshal([]byte(argsJSON), &params); err != nil {
			return marshalResponse(nil, fmt.Errorf("无法解析参数: %v", err))
		}
	}

	var result interface{}
	var err error

	// 根据函数名分发
	switch funcName {
	case "createActor":
		result, err = createActor(params)
	case "sendMessage":
		result, err = sendMessage(params)
	case "stopActor":
		result, err = stopActor(params)
	case "getVersion":
		result = "ProtoActor-Go WASM 0.1.0"
		err = nil
	default:
		err = fmt.Errorf("未知函数: %s", funcName)
	}

	return marshalResponse(result, err)
}

// marshalResponse 序列化响应
func marshalResponse(result interface{}, err error) js.Value {
	var response map[string]interface{}

	if err != nil {
		response = map[string]interface{}{
			"error": err.Error(),
		}
	} else {
		response = map[string]interface{}{
			"result": result,
		}
	}

	jsonBytes, jsonErr := json.Marshal(response)
	if jsonErr != nil {
		errResponse := fmt.Sprintf(`{"error":"无法序列化响应: %v"}`, jsonErr)
		return js.ValueOf(errResponse)
	}

	return js.ValueOf(string(jsonBytes))
}

// callTS 调用 TypeScript 函数
func callTS(funcName string, args ...interface{}) (interface{}, error) {
	argsJSON, err := json.Marshal(args)
	if err != nil {
		return nil, fmt.Errorf("参数序列化失败: %v", err)
	}

	tsBridge := js.Global().Get("__TS_BRIDGE__")
	if tsBridge.IsUndefined() || tsBridge.IsNull() {
		return nil, fmt.Errorf("TypeScript 桥接对象未找到")
	}

	invokeTS := tsBridge.Get("invokeTS")
	if invokeTS.IsUndefined() || invokeTS.IsNull() {
		return nil, fmt.Errorf("invokeTS 函数未找到")
	}

	resultJSON := invokeTS.Invoke(funcName, string(argsJSON)).String()
	if resultJSON == "" {
		return nil, nil
	}

	var result interface{}
	if err := json.Unmarshal([]byte(resultJSON), &result); err != nil {
		return nil, fmt.Errorf("结果解析失败: %v", err)
	}

	return result, nil
}

// createActor 创建一个新的 Actor
func createActor(params []interface{}) (interface{}, error) {
	if len(params) < 1 {
		return nil, fmt.Errorf("需要提供 actorName")
	}

	actorName, ok := params[0].(string)
	if !ok {
		return nil, fmt.Errorf("actorName 必须是字符串")
	}

	id := fmt.Sprintf("actor-%d", nextActorID)
	nextActorID++

	// 将 Actor 添加到注册表
	actorRegistry[id] = true

	// 返回 PID
	return map[string]interface{}{
		"id":      id,
		"address": "local",
		"name":    actorName,
	}, nil
}

// stopActor 停止一个 Actor
func stopActor(params []interface{}) (interface{}, error) {
	if len(params) < 1 {
		return nil, fmt.Errorf("需要提供 PID")
	}

	pidMap, ok := params[0].(map[string]interface{})
	if !ok {
		return nil, fmt.Errorf("PID 必须是对象")
	}

	id, _ := pidMap["id"].(string)
	if id == "" {
		return nil, fmt.Errorf("无效的 PID：缺少 ID")
	}

	// 从注册表中删除 Actor
	delete(actorRegistry, id)

	return map[string]interface{}{
		"success": true,
	}, nil
}

// sendMessage 向 Actor 发送消息
func sendMessage(params []interface{}) (interface{}, error) {
	if len(params) < 2 {
		return nil, fmt.Errorf("需要提供 PID 和 message")
	}

	pidMap, ok := params[0].(map[string]interface{})
	if !ok {
		return nil, fmt.Errorf("PID 必须是对象")
	}

	message, ok := params[1].(map[string]interface{})
	if !ok {
		return nil, fmt.Errorf("消息必须是对象")
	}

	id, _ := pidMap["id"].(string)
	if id == "" {
		return nil, fmt.Errorf("无效的 PID：缺少 ID")
	}

	// 检查 Actor 是否存在
	if !actorRegistry[id] {
		return nil, fmt.Errorf("Actor 不存在: %s", id)
	}

	// 调用 TypeScript 处理函数
	result, err := callTS("handleGreeting", message)
	if err != nil {
		return nil, fmt.Errorf("调用处理函数失败: %v", err)
	}

	return result, nil
}
